home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #3 / Amiga Plus CD - 2002 - No. 03.iso / AmiSoft / Util / Sys / Amberram.lha / AmberRAM / Source / commands.c next >
Encoding:
C/C++ Source or Header  |  2003-01-29  |  38.9 KB  |  2,276 lines

  1. /*
  2.  
  3. File: commands.c
  4. Author: Neil Cafferkey
  5. Copyright (C) 2001-2003 Neil Cafferkey
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  20. MA 02111-1307, USA.
  21.  
  22. */
  23.  
  24.  
  25. #include "handler_protos.h"
  26.  
  27.  
  28. const TEXT utility_name[]=UTILITYNAME;
  29. const TEXT locale_name[]="locale.library";
  30. const TEXT default_vol_name[]="RAM Disc";
  31.  
  32.  
  33.  
  34. /****i* ram.handler/CmdStartup *********************************************
  35. *
  36. *   NAME
  37. *    CmdStartup --
  38. *
  39. *   SYNOPSIS
  40. *    handler = CmdStartup(name,dev_node,
  41. *        proc_port)
  42. *
  43. *    struct Handler *CmdStartup(STRPTR,struct DeviceNode *,
  44. *        struct MsgPort *);
  45. *
  46. *   FUNCTION
  47. *
  48. *   INPUTS
  49. *
  50. *   RESULT
  51. *
  52. *   EXAMPLE
  53. *
  54. *   NOTES
  55. *
  56. *   BUGS
  57. *
  58. *   SEE ALSO
  59. *
  60. ****************************************************************************
  61. *
  62. */
  63.  
  64. struct Handler *CmdStartup(STRPTR name,struct DeviceNode *dev_node,
  65.    struct MsgPort *proc_port)
  66. {
  67.    struct DosList *volume,*dos_list;
  68.    struct Handler *handler;
  69.    struct Object *root_dir;
  70.    struct MsgPort *port;
  71.    LONG error;
  72.    APTR base;
  73.  
  74.    /* Open extra libraries */
  75.  
  76.    error=0;
  77.    base=OpenLibrary(utility_name,UTILITY_VERSION);
  78.    if(base!=NULL)
  79.       UtilityBase=base;
  80.    else
  81.       error=1;
  82.  
  83.    base=OpenLibrary(locale_name,LOCALE_VERSION);
  84.    if(base!=NULL)
  85.       LocaleBase=base;
  86.    else
  87.       error=1;
  88.  
  89.    /* Initialise private handler structure */
  90.  
  91.    handler=AllocMem(sizeof(struct Handler),MEMF_CLEAR);
  92.  
  93.    if(handler==NULL)
  94.       error=IoErr();
  95.  
  96.    if(error==0)
  97.    {
  98.       handler->proc_port=proc_port;
  99.       handler->block_count=MEMBLOCKS(StrSize(default_vol_name))+
  100.          MEMBLOCKS(sizeof(struct Handler));
  101.       handler->min_block_size=MIN_BLOCK_SIZE;
  102.       handler->max_block_size=MAX_BLOCK_SIZE;
  103.  
  104.       dev_node->dn_Task=proc_port;
  105.    }
  106.  
  107.    /* Create a volume dos node */
  108.  
  109.    volume=MyMakeDosEntry(default_vol_name,DLT_VOLUME);
  110.    if(volume==NULL)
  111.       error=IoErr();
  112.  
  113.    if(error==0)
  114.    {
  115.       volume->dol_Task=proc_port;
  116.       DateStamp(&volume->dol_misc.dol_volume.dol_VolumeDate);
  117.       volume->dol_misc.dol_volume.dol_DiskType=ID_DOS_DISK;
  118.  
  119.       /* Put volume node into dos list */
  120.  
  121.       dos_list=LockDosList(LDF_WRITE|LDF_ALL);
  122.       AddDosEntry(volume);
  123.       handler->volume=volume;
  124.       UnLockDosList(LDF_WRITE|LDF_ALL);
  125.    }
  126.  
  127.    /* Open default locale */
  128.  
  129.    handler->locale=OpenLocale(NULL);
  130.  
  131.    /* Initialise notification handling */
  132.  
  133.    NewList((APTR)&handler->notifications);
  134.    port=CreateMsgPort();
  135.    handler->notify_port=port;
  136.    if(port==NULL)
  137.       error=ERROR_NO_FREE_STORE;
  138.  
  139.    /* Create the root directory and get a shared lock on it */
  140.  
  141.    root_dir=CreateObject(handler,default_vol_name,ST_ROOT,NULL);
  142.    handler->root_dir=root_dir;
  143.    if(root_dir!=NULL)
  144.    {
  145.       if(LockObject(handler,root_dir,ACCESS_READ)==NULL)
  146.          error=IoErr();
  147.    }
  148.    else
  149.       error=IoErr();
  150.  
  151.    /* Shut down handler if an error occurred */
  152.  
  153.    if(error!=0)
  154.       CmdDie(handler);
  155.  
  156.    /* Return result */
  157.  
  158.    SetIoErr(error);
  159.    return handler;
  160. }
  161.  
  162.  
  163.  
  164. /****i* ram.handler/CmdDie *************************************************
  165. *
  166. *   NAME
  167. *    CmdDie --
  168. *
  169. *   SYNOPSIS
  170. *    success = CmdDie(handler)
  171. *
  172. *    BOOL CmdDie(struct Handler *);
  173. *
  174. *   FUNCTION
  175. *
  176. *   INPUTS
  177. *
  178. *   RESULT
  179. *
  180. *   EXAMPLE
  181. *
  182. *   NOTES
  183. *
  184. *   BUGS
  185. *
  186. *   SEE ALSO
  187. *
  188. ****************************************************************************
  189. *
  190. */
  191.  
  192. BOOL CmdDie(struct Handler *handler)
  193. {
  194.    struct DosList *volume;
  195.    struct Object *root_dir;
  196.    struct Lock *root_lock;
  197.    LONG error=0;
  198.    APTR base;
  199.  
  200.    if(handler!=NULL)
  201.    {
  202.       root_dir=handler->root_dir;
  203.       if(!(IsListEmpty((struct List *)&root_dir->elements)
  204.          &&IsListEmpty((struct List *)&handler->notifications)
  205.          &&IsListEmpty((struct List *)&root_dir->notifications)))
  206.          error=ERROR_OBJECT_IN_USE;
  207.  
  208.       if(error==0)
  209.       {
  210.          if(root_dir!=NULL)
  211.          {
  212.             root_lock=root_dir->lock;
  213.             if(root_lock!=NULL)
  214.                CmdFreeLock(handler,root_lock);
  215.             DeleteObject(handler,root_dir);
  216.          }
  217.  
  218.          volume=handler->volume;
  219.          if(volume!=NULL)
  220.          {
  221.             RemDosEntry(volume);
  222.             MyFreeDosEntry(volume);
  223.          }
  224.          CloseLocale(handler->locale);
  225.          DeleteMsgPort(handler->notify_port);
  226.          FreeMem(handler,sizeof(struct Handler));
  227.       }
  228.  
  229.       /* Close libraries */
  230.  
  231.       base=LocaleBase;
  232.       if(base!=NULL)
  233.          CloseLibrary(base);
  234.  
  235.       base=UtilityBase;
  236.       if(base!=NULL)
  237.          CloseLibrary(base);
  238.    }
  239.  
  240.    /* Return success indicator */
  241.  
  242.    SetIoErr(error);
  243.    return error==0;
  244. }
  245.  
  246.  
  247.  
  248. /****i* ram.handler/CmdIsFileSystem ****************************************
  249. *
  250. *   NAME
  251. *    CmdIsFileSystem --
  252. *
  253. *   SYNOPSIS
  254. *    result = CmdIsFileSystem()
  255. *
  256. *    BOOL CmdIsFileSystem();
  257. *
  258. *   FUNCTION
  259. *
  260. *   INPUTS
  261. *
  262. *   RESULT
  263. *
  264. *   EXAMPLE
  265. *
  266. *   NOTES
  267. *
  268. *   BUGS
  269. *
  270. *   SEE ALSO
  271. *
  272. ****************************************************************************
  273. *
  274. */
  275.  
  276. BOOL CmdIsFileSystem()
  277. {
  278.    return TRUE;
  279. }
  280.  
  281.  
  282.  
  283. /****i* ram.handler/CmdFind ************************************************
  284. *
  285. *   NAME
  286. *    CmdFind --
  287. *
  288. *   SYNOPSIS
  289. *    success = CmdFind(handler,handle,lock,
  290. *        name,mode)
  291. *
  292. *    BOOL CmdFind(struct Handler *,struct FileHandle *,struct Lock *,
  293. *        TEXT *,ULONG);
  294. *
  295. *   FUNCTION
  296. *
  297. *   INPUTS
  298. *
  299. *   RESULT
  300. *
  301. *   EXAMPLE
  302. *
  303. *   NOTES
  304. *
  305. *   BUGS
  306. *
  307. *   SEE ALSO
  308. *
  309. ****************************************************************************
  310. *
  311. */
  312.  
  313. BOOL CmdFind(struct Handler *handler,struct FileHandle *handle,
  314.    struct Lock *lock,const TEXT *name,ULONG type)
  315. {
  316.    LONG error=0;
  317.    ULONG mode;
  318.    struct Object *file,*parent;
  319.  
  320.    /* Set access mode */
  321.  
  322.    if(type==MODE_OLDFILE)
  323.       mode=ACCESS_READ;
  324.    else
  325.       mode=ACCESS_WRITE;
  326.  
  327.    /* Get file */
  328.  
  329.    if((type==MODE_NEWFILE)&&(handler->locked))
  330.       error=ERROR_DISK_WRITE_PROTECTED;
  331.  
  332.    if(error==0)
  333.    {
  334.       file=GetObject(handler,lock,name,&parent);
  335.       if(parent==NULL)
  336.          error=IoErr();
  337.    }
  338.  
  339.    /* Do any necessary file deletion or creation */
  340.  
  341.    if(error==0)
  342.    {
  343.       name=FilePart(name);
  344.  
  345.       switch(type)
  346.       {
  347.       case MODE_NEWFILE:
  348.          if(file!=NULL)
  349.          {
  350.             if(((struct Node *)file)->ln_Pri>=0)
  351.                error=ERROR_OBJECT_EXISTS;
  352.          }
  353.  
  354.          if(error==0)
  355.          {
  356.             if(!AttemptDeleteObject(handler,file))
  357.                error=IoErr();
  358.             file=NULL;
  359.          }
  360.  
  361.       case MODE_READWRITE:
  362.          if((error==0)&&(file==NULL))
  363.             file=CreateObject(handler,name,ST_FILE,parent);
  364.  
  365.       default:
  366.          if(file==NULL)
  367.             error=IoErr();
  368.       }
  369.    }
  370.  
  371.    /* Get a lock on the file */
  372.  
  373.    if(error==0)
  374.    {
  375.       lock=LockObject(handler,file,mode);
  376.       if(lock==NULL)
  377.          error=IoErr();
  378.       else if(type==MODE_NEWFILE)
  379.          lock->changed=TRUE;
  380.    }
  381.  
  382.    /* Open file */
  383.  
  384.    if(error==0)
  385.    {
  386.       if(!CmdFHFromLock(handle,lock))
  387.       {
  388.          error=IoErr();
  389.          CmdFreeLock(handler,lock);
  390.       }
  391.    }
  392.  
  393.    /* Set error and return success code */
  394.  
  395.    SetIoErr(error);
  396.    return error==0;
  397. }
  398.  
  399.  
  400.  
  401. /****i* ram.handler/CmdFHFromLock ******************************************
  402. *
  403. *   NAME
  404. *    CmdFHFromLock --
  405. *
  406. *   SYNOPSIS
  407. *    success = CmdFHFromLock(handle,lock)
  408. *
  409. *    BOOL CmdFHFromLock(struct FileHandle *,struct Lock *);
  410. *
  411. *   FUNCTION
  412. *
  413. *   INPUTS
  414. *
  415. *   RESULT
  416. *
  417. *   EXAMPLE
  418. *
  419. *   NOTES
  420. *
  421. *   BUGS
  422. *
  423. *   SEE ALSO
  424. *
  425. ****************************************************************************
  426. *
  427. */
  428.  
  429. BOOL CmdFHFromLock(struct FileHandle *handle,struct Lock *lock)
  430. {
  431.    LONG error=0;
  432.    struct Opening *opening;
  433.    struct Object *file;
  434.  
  435.    /* Check if access is allowed */
  436.  
  437.    file=(APTR)((struct FileLock *)lock)->fl_Key;
  438.    if(((struct Node *)file)->ln_Pri!=ST_FILE)
  439.       error=ERROR_OBJECT_WRONG_TYPE;
  440.  
  441.    /* Create and initialise "opening" */
  442.  
  443.    if(error==0)
  444.    {
  445.       opening=AllocMem(sizeof(struct Opening),MEMF_CLEAR);
  446.       if(opening!=NULL)
  447.       {
  448.          opening->file=file;
  449.          opening->block=(struct Block *)file->elements.mlh_Head;
  450.       }
  451.       else
  452.          error=IoErr();
  453.    }
  454.  
  455.    /* Put address of opening in file handle */
  456.  
  457.    handle->fh_Arg1=(PINT)opening;
  458.  
  459.    /* Set error and return success code */
  460.  
  461.    SetIoErr(error);
  462.    return error==0;
  463. }
  464.  
  465.  
  466.  
  467. /****i* ram.handler/CmdEnd *************************************************
  468. *
  469. *   NAME
  470. *    CmdEnd --
  471. *
  472. *   SYNOPSIS
  473. *    success = CmdEnd(handler,opening)
  474. *
  475. *    BOOL CmdEnd(struct Handler *,struct Opening *);
  476. *
  477. *   FUNCTION
  478. *
  479. *   INPUTS
  480. *
  481. *   RESULT
  482. *
  483. *   EXAMPLE
  484. *
  485. *   NOTES
  486. *
  487. *   BUGS
  488. *
  489. *   SEE ALSO
  490. *
  491. ****************************************************************************
  492. *
  493. */
  494.  
  495. BOOL CmdEnd(struct Handler *handler,struct Opening *opening)
  496. {
  497.    struct Object *file,*parent;
  498.    struct Lock *lock;
  499.    LONG error;
  500.  
  501.    /* Close file and update its date and flags */
  502.  
  503.    error=0;
  504.    file=opening->file;
  505.    lock=file->lock;
  506.    if(lock->changed)
  507.    {
  508.       if(!handler->locked)
  509.       {
  510.          file->protection&=~FIBF_ARCHIVE;
  511.          DateStamp(&file->date);
  512.          parent=file->parent;
  513.          parent->protection&=~FIBF_ARCHIVE;
  514.          CopyMem(&file->date,&parent->date,sizeof(struct DateStamp));
  515.  
  516.          NotifyAll(handler,file,TRUE);
  517.       }
  518.       else
  519.          error=ERROR_DISK_WRITE_PROTECTED;
  520.    }
  521.  
  522.    if(error==0)
  523.    {
  524.       CmdFreeLock(handler,lock);
  525.       FreeMem(opening,sizeof(struct Opening));
  526.    }
  527.  
  528.    /* Return success indicator */
  529.  
  530.    SetIoErr(error);
  531.    return error==0;
  532. }
  533.  
  534.  
  535.  
  536. /****i* ram.handler/CmdRead ************************************************
  537. *
  538. *   NAME
  539. *    CmdRead --
  540. *
  541. *   SYNOPSIS
  542. *    actual_length = CmdRead(opening,buffer,length)
  543. *
  544. *    UPINT CmdRead(struct Opening *,UBYTE *,UPINT);
  545. *
  546. *   FUNCTION
  547. *
  548. *   INPUTS
  549. *
  550. *   RESULT
  551. *
  552. *   EXAMPLE
  553. *
  554. *   NOTES
  555. *
  556. *   BUGS
  557. *
  558. *   SEE ALSO
  559. *
  560. ****************************************************************************
  561. *
  562. */
  563.  
  564. UPINT CmdRead(struct Opening *opening,UBYTE *buffer,UPINT length)
  565. {
  566.    LONG error;
  567.    struct Object *file;
  568.  
  569.    /* Read file if it isn't read protected */
  570.  
  571.    error=0;
  572.    file=opening->file;
  573.  
  574.    if(file->protection&FIBF_READ)
  575.       error=ERROR_READ_PROTECTED;
  576.  
  577.    if(error==0)
  578.    {
  579.       length=ReadData(opening,buffer,length);
  580.       error=IoErr();
  581.    }
  582.    else
  583.    {
  584.       length=-1;
  585.    }
  586.  
  587.    /* Return number of bytes read */
  588.  
  589.    SetIoErr(error);
  590.    return length;
  591. }
  592.  
  593.  
  594.  
  595. /****i* ram.handler/CmdWrite ***********************************************
  596. *
  597. *   NAME
  598. *    CmdWrite --
  599. *
  600. *   SYNOPSIS
  601. *    actual_length = CmdWrite(handler,opening,buffer,length)
  602. *
  603. *    UPINT CmdWrite(struct Handler *,struct Opening *,UBYTE *,UPINT);
  604. *
  605. *   FUNCTION
  606. *
  607. *   INPUTS
  608. *
  609. *   RESULT
  610. *
  611. *   EXAMPLE
  612. *
  613. *   NOTES
  614. *
  615. *   BUGS
  616. *
  617. *   SEE ALSO
  618. *
  619. ****************************************************************************
  620. *
  621. */
  622.  
  623. UPINT CmdWrite(struct Handler *handler,struct Opening *opening,
  624.    UBYTE *buffer,UPINT length)
  625. {
  626.    LONG error;
  627.    struct Object *file;
  628.    struct Lock *lock;
  629.  
  630.    /* Write to file if it isn't write protected */
  631.  
  632.    error=0;
  633.    file=opening->file;
  634.    lock=file->lock;
  635.  
  636. #ifndef AMIGAOS
  637.    if(((struct FileLock *)lock)->fl_Access==ACCESS_READ)
  638.       error=ERROR_OBJECT_IN_USE;
  639.                                  /* ERROR_WRONG_LOCK_TYPE would be better */
  640. #endif
  641.  
  642.    if(file->protection&FIBF_WRITE)
  643.       error=ERROR_WRITE_PROTECTED;
  644.  
  645.    if(handler->locked)
  646.       error=ERROR_DISK_WRITE_PROTECTED;
  647.  
  648.    if(error==0)
  649.    {
  650.       length=WriteData(handler,opening,buffer,length);
  651.       error=IoErr();
  652.       if(length>0)
  653.          lock->changed=TRUE;
  654.    }
  655.    else
  656.    {
  657.       length=-1;
  658.    }
  659.  
  660.    /* Return number of bytes written */
  661.  
  662.    SetIoErr(error);
  663.    return length;
  664. }
  665.  
  666.  
  667.  
  668. /****i* ram.handler/CmdSeek ************************************************
  669. *
  670. *   NAME
  671. *    CmdSeek --
  672. *
  673. *   SYNOPSIS
  674. *    old_pos = CmdSeek(opening,offset,mode)
  675. *
  676. *    PINT CmdSeek(struct Opening *,PINT,LONG);
  677. *
  678. *   FUNCTION
  679. *
  680. *   INPUTS
  681. *
  682. *   RESULT
  683. *
  684. *   EXAMPLE
  685. *
  686. *   NOTES
  687. *
  688. *   BUGS
  689. *
  690. *   SEE ALSO
  691. *
  692. ****************************************************************************
  693. *
  694. * Note: Being at EOF is represented by the current block being the dummy
  695. * tail and the block position being zero.
  696. *
  697. */
  698.  
  699. UPINT CmdSeek(struct Opening *opening,PINT offset,LONG mode)
  700. {
  701.    struct Block *block;
  702.    struct Object *file;
  703.    UPINT block_pos,block_length,remainder,old_pos,new_pos;
  704.  
  705.    /* Get starting point */
  706.  
  707.    file=opening->file;
  708.    old_pos=opening->pos;
  709.  
  710.    if(mode==OFFSET_BEGINNING)
  711.    {
  712.       block=(APTR)file->elements.mlh_Head;
  713.       new_pos=block_pos=0;
  714.    }
  715.    else if(mode==OFFSET_CURRENT)
  716.    {
  717.       block=opening->block;
  718.       block_pos=opening->block_pos;
  719.       new_pos=old_pos;
  720.    }
  721.    else
  722.    {
  723.       block=(APTR)&file->elements.mlh_Tail;
  724.       block_pos=0;
  725.       new_pos=file->length;
  726.    }
  727.  
  728.    /* Check new position is within file */
  729.  
  730.    new_pos+=offset;
  731.    if(new_pos>file->length)
  732.    {
  733.       SetIoErr(ERROR_SEEK_ERROR);
  734.       return -1;
  735.    }
  736.  
  737.    if(offset>=0)
  738.    {
  739.       /* Go forwards */
  740.  
  741.       block_length=GetBlockLength(file,block);
  742.       remainder=offset+block_pos;
  743.       while((remainder>=block_length)&&(remainder>0))
  744.       {
  745.          remainder-=block_length;
  746.          block=(APTR)((struct MinNode *)block)->mln_Succ;
  747.          block_length=GetBlockLength(file,block);
  748.       }
  749.  
  750.       block_pos=remainder;
  751.    }
  752.    else
  753.    {
  754.       /* Go backwards */
  755.  
  756.       block_length=block_pos;
  757.       remainder=-offset;
  758.       while(remainder>block_length)
  759.       {
  760.          remainder-=block_length;
  761.          block=(APTR)((struct MinNode *)block)->mln_Pred;
  762.          block_length=GetBlockLength(file,block);
  763.       }
  764.  
  765.       block_pos=block_length-remainder;
  766.    }
  767.  
  768.    /* Record new position for next access */
  769.  
  770.    opening->block=block;
  771.    opening->block_pos=block_pos;
  772.    opening->pos=new_pos;
  773.  
  774.    /* Return old position */
  775.  
  776.    return old_pos;
  777. }
  778.  
  779.  
  780.  
  781. /****i* ram.handler/CmdSetFileSize *****************************************
  782. *
  783. *   NAME
  784. *    CmdSetFileSize --
  785. *
  786. *   SYNOPSIS
  787. *    new_length = CmdSetFileSize(handler,opening,offset,mode)
  788. *
  789. *    PINT CmdSetFileSize(struct Handler *,struct Opening *,PINT,LONG);
  790. *
  791. *   FUNCTION
  792. *
  793. *   INPUTS
  794. *
  795. *   RESULT
  796. *
  797. *   EXAMPLE
  798. *
  799. *   NOTES
  800. *
  801. *   BUGS
  802. *
  803. *   SEE ALSO
  804. *
  805. ****************************************************************************
  806. *
  807. */
  808.  
  809. PINT CmdSetFileSize(struct Handler *handler,struct Opening *opening,
  810.    PINT offset,LONG mode)
  811. {
  812.    LONG error=0,new_size;
  813.    struct Object *file;
  814.    struct Lock *lock;
  815.  
  816.    /* Change file size if it's open for writing */
  817.  
  818.    file=opening->file;
  819.    lock=file->lock;
  820.  
  821.    if(((struct FileLock *)lock)->fl_Access==ACCESS_READ)
  822.       error=ERROR_OBJECT_IN_USE;
  823.    if(file->protection&FIBF_WRITE)
  824.       error=ERROR_WRITE_PROTECTED;
  825.    if(handler->locked)
  826.       error=ERROR_DISK_WRITE_PROTECTED;
  827.  
  828.    if(error==0)
  829.    {
  830.       new_size=ChangeFileSize(handler,opening,offset,mode);
  831.       if(new_size==-1)
  832.          error=IoErr();
  833.       else
  834.          lock->changed=TRUE;
  835.    }
  836.    else
  837.       new_size=-1;
  838.  
  839.    /* Return new file size */
  840.  
  841.    SetIoErr(error);
  842.    return new_size;
  843. }
  844.  
  845.  
  846.  
  847. /****i* ram.handler/CmdLocateObject ****************************************
  848. *
  849. *   NAME
  850. *    CmdLocateObject --
  851. *
  852. *   SYNOPSIS
  853. *    lock = CmdLocateObject(handler,lock,name,
  854. *        mode)
  855. *
  856. *    struct Lock *CmdLocateObject(struct Handler *,struct Lock *,TEXT *,
  857. *        ULONG);
  858. *
  859. *   FUNCTION
  860. *
  861. *   INPUTS
  862. *
  863. *   RESULT
  864. *
  865. *   EXAMPLE
  866. *
  867. *   NOTES
  868. *
  869. *   BUGS
  870. *
  871. *   SEE ALSO
  872. *
  873. ****************************************************************************
  874. *
  875. */
  876.  
  877. struct Lock *CmdLocateObject(struct Handler *handler,
  878.    struct Lock *lock,const TEXT *name,ULONG mode)
  879. {
  880.    struct Object *object;
  881.  
  882.    /* Find the object and lock it */
  883.  
  884.    object=GetObject(handler,lock,name,NULL);
  885.  
  886.    if(object!=NULL)
  887.       lock=LockObject(handler,object,mode);
  888.    else
  889.       lock=NULL;
  890.  
  891.    /* Return result */
  892.  
  893.    return lock;
  894. }
  895.  
  896.  
  897.  
  898. /****i* ram.handler/CmdFreeLock ********************************************
  899. *
  900. *   NAME
  901. *    CmdFreeLock --
  902. *
  903. *   SYNOPSIS
  904. *    success = CmdFreeLock(handler,lock)
  905. *
  906. *    BOOL CmdFreeLock(struct Handler *,struct Lock *);
  907. *
  908. *   FUNCTION
  909. *
  910. *   INPUTS
  911. *    lock - May be NULL.
  912. *
  913. *   RESULT
  914. *
  915. *   EXAMPLE
  916. *
  917. *   NOTES
  918. *
  919. *   BUGS
  920. *
  921. *   SEE ALSO
  922. *
  923. ****************************************************************************
  924. *
  925. */
  926.  
  927. BOOL CmdFreeLock(struct Handler *handler,struct Lock *lock)
  928. {
  929.    struct Object *object;
  930.  
  931.    if(lock!=NULL)
  932.    {
  933.       object=(APTR)((struct FileLock *)lock)->fl_Key;
  934.  
  935.       handler->lock_count--;
  936.       if((--lock->lock_count)==0)
  937.       {
  938.          FreeMem(lock,sizeof(struct Lock));
  939.          object->lock=NULL;
  940.       }
  941.    }
  942.  
  943.    return TRUE;
  944. }
  945.  
  946.  
  947.  
  948. /****i* ram.handler/CmdCopyDir *********************************************
  949. *
  950. *   NAME
  951. *    CmdCopyDir --
  952. *
  953. *   SYNOPSIS
  954. *    lock = CmdCopyDir(handler,lock)
  955. *
  956. *    struct Lock *CmdCopyDir(struct Handler *,struct Lock *);
  957. *
  958. *   FUNCTION
  959. *
  960. *   INPUTS
  961. *
  962. *   RESULT
  963. *
  964. *   EXAMPLE
  965. *
  966. *   NOTES
  967. *
  968. *   BUGS
  969. *
  970. *   SEE ALSO
  971. *
  972. ****************************************************************************
  973. *
  974. */
  975.  
  976. struct Lock *CmdCopyDir(struct Handler *handler,struct Lock *lock)
  977. {
  978.    lock=FixLock(handler,lock);
  979.    lock=LockObject(handler,(APTR)((struct FileLock *)lock)->fl_Key,
  980.       ACCESS_READ);
  981.  
  982.    return lock;
  983. }
  984.  
  985.  
  986.  
  987. /****i* ram.handler/CmdCopyDirFH *******************************************
  988. *
  989. *   NAME
  990. *    CmdCopyDirFH --
  991. *
  992. *   SYNOPSIS
  993. *    lock = CmdCopyDirFH(handler,opening)
  994. *
  995. *    struct Lock *CmdCopyDirFH(struct Handler *,struct Opening *);
  996. *
  997. *   FUNCTION
  998. *
  999. *   INPUTS
  1000. *
  1001. *   RESULT
  1002. *
  1003. *   EXAMPLE
  1004. *
  1005. *   NOTES
  1006. *
  1007. *   BUGS
  1008. *
  1009. *   SEE ALSO
  1010. *
  1011. ****************************************************************************
  1012. *
  1013. */
  1014.  
  1015. struct Lock *CmdCopyDirFH(struct Handler *handler,
  1016.    struct Opening *opening)
  1017. {
  1018.    return LockObject(handler,opening->file,ACCESS_READ);
  1019. }
  1020.  
  1021.  
  1022.  
  1023. /****i* ram.handler/CmdParent **********************************************
  1024. *
  1025. *   NAME
  1026. *    CmdParent --
  1027. *
  1028. *   SYNOPSIS
  1029. *    lock = CmdParent(handler,lock)
  1030. *
  1031. *    struct Lock *CmdParent(struct Handler *,struct Lock *);
  1032. *
  1033. *   FUNCTION
  1034. *
  1035. *   INPUTS
  1036. *
  1037. *   RESULT
  1038. *
  1039. *   EXAMPLE
  1040. *
  1041. *   NOTES
  1042. *
  1043. *   BUGS
  1044. *
  1045. *   SEE ALSO
  1046. *
  1047. ****************************************************************************
  1048. *
  1049. */
  1050.  
  1051. struct Lock *CmdParent(struct Handler *handler,struct Lock *lock)
  1052. {
  1053.    struct Object *parent;
  1054.    LONG error=0;
  1055.  
  1056.    lock=FixLock(handler,lock);
  1057.  
  1058.    parent=((struct Object *)((struct FileLock *)lock)->fl_Key)->parent;
  1059.    if(parent!=NULL)
  1060.    {
  1061.       lock=LockObject(handler,parent,ACCESS_READ);
  1062.       if(lock==NULL)
  1063.          error=IoErr();
  1064.    }
  1065.    else
  1066.       lock=NULL;
  1067.  
  1068.    SetIoErr(error);
  1069.    return lock;
  1070. }
  1071.  
  1072.  
  1073.  
  1074. /****i* ram.handler/CmdParentFH ********************************************
  1075. *
  1076. *   NAME
  1077. *    CmdParentFH --
  1078. *
  1079. *   SYNOPSIS
  1080. *    lock = CmdParentFH(handler,opening)
  1081. *
  1082. *    struct Lock *CmdParentFH(struct Handler *,struct Opening *);
  1083. *
  1084. *   FUNCTION
  1085. *
  1086. *   INPUTS
  1087. *
  1088. *   RESULT
  1089. *
  1090. *   EXAMPLE
  1091. *
  1092. *   NOTES
  1093. *
  1094. *   BUGS
  1095. *
  1096. *   SEE ALSO
  1097. *
  1098. ****************************************************************************
  1099. *
  1100. */
  1101.  
  1102. struct Lock *CmdParentFH(struct Handler *handler,
  1103.    struct Opening *opening)
  1104. {
  1105.    struct Object *parent;
  1106.    struct Lock *lock;
  1107.  
  1108.    parent=opening->file->parent;
  1109.    lock=LockObject(handler,parent,ACCESS_READ);
  1110.  
  1111.    return lock;
  1112. }
  1113.  
  1114.  
  1115.  
  1116. /****i* ram.handler/CmdSameLock ********************************************
  1117. *
  1118. *   NAME
  1119. *    CmdSameLock --
  1120. *
  1121. *   SYNOPSIS
  1122. *    result = CmdSameLock(lock1,lock2)
  1123. *
  1124. *    BOOL CmdSameLock(struct Lock *,struct Lock *);
  1125. *
  1126. *   FUNCTION
  1127. *
  1128. *   INPUTS
  1129. *
  1130. *   RESULT
  1131. *
  1132. *   EXAMPLE
  1133. *
  1134. *   NOTES
  1135. *
  1136. *   BUGS
  1137. *
  1138. *   SEE ALSO
  1139. *
  1140. ****************************************************************************
  1141. *
  1142. */
  1143.  
  1144. BOOL CmdSameLock(struct Lock *lock1,struct Lock *lock2)
  1145. {
  1146.    SetIoErr(0);
  1147.    return lock1==lock2;
  1148. }
  1149.  
  1150.  
  1151.  
  1152. /****i* ram.handler/CmdCreateDir *******************************************
  1153. *
  1154. *   NAME
  1155. *    CmdCreateDir --
  1156. *
  1157. *   SYNOPSIS
  1158. *    lock = CmdCreateDir(handler,lock,name)
  1159. *
  1160. *    struct Lock *CmdCreateDir(struct Handler *,struct Lock *,TEXT *);
  1161. *
  1162. *   FUNCTION
  1163. *
  1164. *   INPUTS
  1165. *
  1166. *   RESULT
  1167. *
  1168. *   EXAMPLE
  1169. *
  1170. *   NOTES
  1171. *
  1172. *   BUGS
  1173. *
  1174. *   SEE ALSO
  1175. *
  1176. ****************************************************************************
  1177. *
  1178. */
  1179.  
  1180. struct Lock *CmdCreateDir(struct Handler *handler,
  1181.    struct Lock *lock,const TEXT *name)
  1182. {
  1183.    struct Object *dir,*parent;
  1184.    LONG error=0;
  1185.  
  1186.    /* Find parent directory and possible name clash */
  1187.  
  1188.    dir=GetObject(handler,lock,name,&parent);
  1189.    lock=NULL;
  1190.  
  1191.    /* Create a new directory */
  1192.  
  1193.    if(dir==NULL)
  1194.    {
  1195.       if(parent!=NULL)
  1196.       {
  1197.          if(!handler->locked)
  1198.          {
  1199.             dir=CreateObject(handler,FilePart(name),ST_USERDIR,parent);
  1200.             if(dir!=NULL)
  1201.             {
  1202.                lock=LockObject(handler,dir,ACCESS_WRITE);
  1203.                if(lock!=NULL)
  1204.                {
  1205.                   MatchNotifyRequests(handler);
  1206.                   NotifyAll(handler,dir,FALSE);
  1207.                }
  1208.                else
  1209.                {
  1210.                   error=IoErr();
  1211.                   DeleteObject(handler,dir);
  1212.                }
  1213.             }
  1214.             else
  1215.                error=IoErr();
  1216.          }
  1217.          else
  1218.             error=ERROR_DISK_WRITE_PROTECTED;
  1219.       }
  1220.       else
  1221.          error=ERROR_OBJECT_NOT_FOUND;
  1222.    }
  1223.    else
  1224.       error=ERROR_OBJECT_EXISTS;
  1225.  
  1226.    /* Set error code and return lock on new directory */
  1227.  
  1228.    SetIoErr(error);
  1229.    return lock;
  1230. }
  1231.  
  1232.  
  1233.  
  1234. /****i* ram.handler/CmdExamineObject ***************************************
  1235. *
  1236. *   NAME
  1237. *    CmdExamineObject --
  1238. *
  1239. *   SYNOPSIS
  1240. *    success = CmdExamineObject(handler,lock,
  1241. *        info)
  1242. *
  1243. *    BOOL CmdExamineObject(struct Handler *,struct Lock *,
  1244. *        struct FileInfoBlock *);
  1245. *
  1246. *   FUNCTION
  1247. *
  1248. *   INPUTS
  1249. *
  1250. *   RESULT
  1251. *
  1252. *   EXAMPLE
  1253. *
  1254. *   NOTES
  1255. *
  1256. *   BUGS
  1257. *
  1258. *   SEE ALSO
  1259. *
  1260. ****************************************************************************
  1261. *
  1262. */
  1263.  
  1264. BOOL CmdExamineObject(struct Handler *handler,struct Lock *lock,
  1265.    struct FileInfoBlock *info)
  1266. {
  1267.    lock=FixLock(handler,lock);
  1268.    return ExamineObject(handler,(APTR)((struct FileLock *)lock)->fl_Key,
  1269.       info);
  1270. }
  1271.  
  1272.  
  1273.  
  1274. /****i* ram.handler/CmdExamineFH *******************************************
  1275. *
  1276. *   NAME
  1277. *    CmdExamineFH --
  1278. *
  1279. *   SYNOPSIS
  1280. *    success = CmdExamineFH(handler,opening,
  1281. *        info)
  1282. *
  1283. *    BOOL CmdExamineFH(struct Handler *,struct Opening *,
  1284. *        struct FileInfoBlock *);
  1285. *
  1286. *   FUNCTION
  1287. *
  1288. *   INPUTS
  1289. *
  1290. *   RESULT
  1291. *
  1292. *   EXAMPLE
  1293. *
  1294. *   NOTES
  1295. *
  1296. *   BUGS
  1297. *
  1298. *   SEE ALSO
  1299. *
  1300. ****************************************************************************
  1301. *
  1302. */
  1303.  
  1304. BOOL CmdExamineFH(struct Handler *handler,struct Opening *opening,
  1305.    struct FileInfoBlock *info)
  1306. {
  1307.    return ExamineObject(handler,opening->file,info);
  1308. }
  1309.  
  1310.  
  1311.  
  1312. /****i* ram.handler/CmdExamineNext *****************************************
  1313. *
  1314. *   NAME
  1315. *    CmdExamineNext --
  1316. *
  1317. *   SYNOPSIS
  1318. *    success = CmdExamineNext(handler,info)
  1319. *
  1320. *    BOOL CmdExamineNext(struct Handler *,struct FileInfoBlock *);
  1321. *
  1322. *   FUNCTION
  1323. *
  1324. *   INPUTS
  1325. *
  1326. *   RESULT
  1327. *
  1328. *   EXAMPLE
  1329. *
  1330. *   NOTES
  1331. *
  1332. *   BUGS
  1333. *
  1334. *   SEE ALSO
  1335. *
  1336. ****************************************************************************
  1337. *
  1338. */
  1339.  
  1340. BOOL CmdExamineNext(struct Handler *handler,struct FileInfoBlock *info)
  1341. {
  1342.    return ExamineObject(handler,NULL,info);
  1343. }
  1344.  
  1345.  
  1346.  
  1347. /****i* ram.handler/CmdInfo ************************************************
  1348. *
  1349. *   NAME
  1350. *    CmdInfo --
  1351. *
  1352. *   SYNOPSIS
  1353. *    success = CmdInfo(handler,info_data)
  1354. *
  1355. *    BOOL CmdExamineObject(struct Handler *,struct InfoData *);
  1356. *
  1357. *   FUNCTION
  1358. *
  1359. *   INPUTS
  1360. *
  1361. *   RESULT
  1362. *
  1363. *   EXAMPLE
  1364. *
  1365. *   NOTES
  1366. *
  1367. *   BUGS
  1368. *
  1369. *   SEE ALSO
  1370. *
  1371. ****************************************************************************
  1372. *
  1373. */
  1374.  
  1375. BOOL CmdInfo(struct Handler *handler,struct InfoData *info_data)
  1376. {
  1377.    LONG disk_state;
  1378.  
  1379.    info_data->id_NumSoftErrors=0;
  1380.    info_data->id_UnitNumber=0;
  1381.    if(handler->locked)
  1382.       disk_state=ID_WRITE_PROTECTED;
  1383.    else
  1384.       disk_state=ID_VALIDATED;
  1385.    info_data->id_DiskState=disk_state;
  1386.    info_data->id_NumBlocks=handler->block_count
  1387.       +MEMBLOCKS(AvailMem(MEMF_ANY));
  1388.    info_data->id_NumBlocksUsed=handler->block_count;
  1389.    info_data->id_BytesPerBlock=MEM_BLOCKSIZE;
  1390.    info_data->id_DiskType=ID_DOS_DISK;
  1391.    info_data->id_VolumeNode=MKBADDR(handler->volume);
  1392.    if(handler->lock_count>1)
  1393.       info_data->id_InUse=DOSTRUE;
  1394.    else
  1395.       info_data->id_InUse=DOSFALSE;
  1396.  
  1397.    return TRUE;
  1398. }
  1399.  
  1400.  
  1401.  
  1402. /****i* ram.handler/CmdSetProtect ******************************************
  1403. *
  1404. *   NAME
  1405. *    CmdSetProtect --
  1406. *
  1407. *   SYNOPSIS
  1408. *    success = CmdSetProtect(handler,lock,name,flags)
  1409. *
  1410. *    BOOL CmdSetProtect(struct Handler *,struct Lock *,TEXT *,ULONG);
  1411. *
  1412. *   FUNCTION
  1413. *
  1414. *   INPUTS
  1415. *
  1416. *   RESULT
  1417. *
  1418. *   EXAMPLE
  1419. *
  1420. *   NOTES
  1421. *
  1422. *   BUGS
  1423. *
  1424. *   SEE ALSO
  1425. *
  1426. ****************************************************************************
  1427. *
  1428. */
  1429.  
  1430. BOOL CmdSetProtect(struct Handler *handler,struct Lock *lock,
  1431.    const TEXT *name,ULONG flags)
  1432. {
  1433.    LONG error;
  1434.    struct Object *object;
  1435.  
  1436.    /* Set new protection flags if object isn't in use */
  1437.  
  1438.    error=0;
  1439.    object=GetObject(handler,lock,name,NULL);
  1440.    if(object!=NULL)
  1441.    {
  1442.       if(handler->locked)
  1443.          error=ERROR_DISK_WRITE_PROTECTED;
  1444.  
  1445.       if(error==0)
  1446.       {
  1447.          object=GetRealObject(object);
  1448.          if(object->lock==NULL)
  1449.          {
  1450.             object->protection=flags;
  1451.             NotifyAll(handler,object,TRUE);
  1452.          }
  1453.          else
  1454.             error=ERROR_OBJECT_IN_USE;
  1455.       }
  1456.    }
  1457.    else
  1458.       error=IoErr();
  1459.  
  1460.    /* Return result */
  1461.  
  1462.    SetIoErr(error);
  1463.    return error==0;
  1464. }
  1465.  
  1466.  
  1467.  
  1468. /****i* ram.handler/CmdSetComment ******************************************
  1469. *
  1470. *   NAME
  1471. *    CmdSetComment --
  1472. *
  1473. *   SYNOPSIS
  1474. *    success = CmdSetComment(handler,lock,name,comment)
  1475. *
  1476. *    BOOL CmdSetComment(struct Handler *,struct Lock *,TEXT *,TEXT *);
  1477. *
  1478. *   FUNCTION
  1479. *
  1480. *   INPUTS
  1481. *
  1482. *   RESULT
  1483. *
  1484. *   EXAMPLE
  1485. *
  1486. *   NOTES
  1487. *
  1488. *   BUGS
  1489. *
  1490. *   SEE ALSO
  1491. *
  1492. ****************************************************************************
  1493. *
  1494. */
  1495.  
  1496. BOOL CmdSetComment(struct Handler *handler,struct Lock *lock,
  1497.    const TEXT *name,const TEXT *comment)
  1498. {
  1499.    LONG error;
  1500.    struct Object *object;
  1501.    const TEXT *p;
  1502.    TEXT ch;
  1503.    struct Locale *locale;
  1504.    PINT block_diff;
  1505.  
  1506.    /* Get object */
  1507.  
  1508.    error=0;
  1509.    object=GetObject(handler,lock,name,NULL);
  1510.    if(object==NULL)
  1511.       error=IoErr();
  1512.  
  1513.    /* Check comment isn't too long */
  1514.  
  1515.    if(StrSize(comment)>sizeof(((struct FileInfoBlock *)NULL)->fib_Comment))
  1516.       error=ERROR_COMMENT_TOO_BIG;
  1517.  
  1518.    /* Check comment doesn't have any strange characters in it */
  1519.  
  1520.    locale=handler->locale;
  1521.    for(p=comment;(ch=*p)!='\0';p++)
  1522.       if(!IsPrint(locale,ch)||IsCntrl(locale,ch))
  1523.          error=ERROR_INVALID_COMPONENT_NAME;
  1524.  
  1525.    /* Check volume isn't write-protected */
  1526.  
  1527.    if(handler->locked)
  1528.       error=ERROR_DISK_WRITE_PROTECTED;
  1529.  
  1530.    /* Store new comment */
  1531.  
  1532.    if(error==0)
  1533.    {
  1534.       block_diff=SetString(&object->comment,comment);
  1535.       if(block_diff==-1)
  1536.          error=IoErr();
  1537.       else
  1538.       {
  1539.          object->block_count+=block_diff;
  1540.          handler->block_count+=block_diff;
  1541.       }
  1542.    }
  1543.  
  1544.    /* Notify interested parties */
  1545.  
  1546.    if(error==0)
  1547.    {
  1548.       NotifyAll(handler,object,FALSE);
  1549.    }
  1550.  
  1551.    /* Return result */
  1552.  
  1553.    SetIoErr(error);
  1554.    return error==0;
  1555. }
  1556.  
  1557.  
  1558.  
  1559. /****i* ram.handler/CmdRenameObject ****************************************
  1560. *
  1561. *   NAME
  1562. *    CmdRenameObject --
  1563. *
  1564. *   SYNOPSIS
  1565. *    success = CmdRenameObject(handler,old_lock,old_name
  1566. *        new_lock,new_name)
  1567. *
  1568. *    BOOL CmdRenameObject(struct Handler *,struct Lock *,STRPTR,
  1569. *        struct Lock *,STRPTR);
  1570. *
  1571. *   FUNCTION
  1572. *
  1573. *   INPUTS
  1574. *
  1575. *   RESULT
  1576. *
  1577. *   EXAMPLE
  1578. *
  1579. *   NOTES
  1580. *
  1581. *   BUGS
  1582. *
  1583. *   SEE ALSO
  1584. *
  1585. ****************************************************************************
  1586. *
  1587. */
  1588.  
  1589. BOOL CmdRenameObject(struct Handler *handler,struct Lock *old_lock,
  1590.    STRPTR old_name,struct Lock *new_lock,STRPTR new_name)
  1591. {
  1592.    struct Object *parent,*object,*duplicate,*p;
  1593.    LONG error=0;
  1594.  
  1595.    /* Get object to be moved */
  1596.  
  1597.    object=GetObject(handler,old_lock,old_name,NULL);
  1598.    if(object==NULL)
  1599.       error=IoErr();
  1600.  
  1601.    /* Get destination directory and check if a different object already has
  1602.       the target name */
  1603.  
  1604.    duplicate=GetObject(handler,new_lock,new_name,&parent);
  1605.    if((duplicate!=NULL)&&(duplicate!=object))
  1606.       error=ERROR_OBJECT_EXISTS;
  1607.    if(parent==NULL)
  1608.       error=IoErr();
  1609.  
  1610.    /* Check for a circular rename */
  1611.  
  1612.    for(p=parent;p!=NULL;p=p->parent)
  1613.    {
  1614.       if(p==object)
  1615.          error=ERROR_OBJECT_NOT_FOUND;
  1616.    }
  1617.  
  1618.    /* Check volume isn't write-protected */
  1619.  
  1620.    if(handler->locked)
  1621.       error=ERROR_DISK_WRITE_PROTECTED;
  1622.  
  1623.    /* Give the object its new name */
  1624.  
  1625.    if(error==0)
  1626.    {
  1627.       if(!SetName(handler,object,FilePart(new_name)))
  1628.          error=IoErr();
  1629.    }
  1630.  
  1631.    if(error==0)
  1632.    {
  1633.       if(object!=duplicate)
  1634.       {
  1635.          /* Remove object from old parent and place it in new parent */
  1636.  
  1637.          Remove((struct Node *)object);
  1638.          AddTail((struct List *)&parent->elements,(struct Node *)object);
  1639.          object->parent=parent;
  1640.  
  1641.          /* Update notifications */
  1642.  
  1643.          NotifyAll(handler,object,FALSE);
  1644.          UnmatchNotifyRequests(handler,object);
  1645.          MatchNotifyRequests(handler);
  1646.       }
  1647.       NotifyAll(handler,object,FALSE);
  1648.    }
  1649.  
  1650.    /* Return success indicator */
  1651.  
  1652.    SetIoErr(error);
  1653.    return error==0;
  1654. }
  1655.  
  1656.  
  1657.  
  1658. /****i* ram.handler/CmdRenameDisk ******************************************
  1659. *
  1660. *   NAME
  1661. *    CmdRenameDisk --
  1662. *
  1663. *   SYNOPSIS
  1664. *    success = CmdRenameDisk(handler,new_name)
  1665. *
  1666. *    BOOL CmdRenameDisk(struct Handler *,STRPTR);
  1667. *
  1668. *   FUNCTION
  1669. *
  1670. *   INPUTS
  1671. *
  1672. *   RESULT
  1673. *
  1674. *   EXAMPLE
  1675. *
  1676. *   NOTES
  1677. *
  1678. *   BUGS
  1679. *
  1680. *   SEE ALSO
  1681. *
  1682. ****************************************************************************
  1683. *
  1684. */
  1685.  
  1686. BOOL CmdRenameDisk(struct Handler *handler,STRPTR new_name)
  1687. {
  1688.    LONG error=0;
  1689.  
  1690.    /* Check volume isn't write-protected */
  1691.  
  1692.    if(handler->locked)
  1693.       error=ERROR_DISK_WRITE_PROTECTED;
  1694.  
  1695.    /* Rename volume's DOS entry and root directory */
  1696.  
  1697.    if(error==0)
  1698.       if(!SetName(handler,handler->root_dir,new_name))
  1699.          error=IoErr();
  1700.  
  1701.    if(error==0)
  1702.       if(!MyRenameDosEntry(handler->volume,new_name))
  1703.          error=IoErr();
  1704.  
  1705.    /* Return success indicator */
  1706.  
  1707.    SetIoErr(error);
  1708.    return error==0;
  1709. }
  1710.  
  1711.  
  1712.  
  1713. /****i* ram.handler/CmdSetDate *********************************************
  1714. *
  1715. *   NAME
  1716. *    CmdSetDate --
  1717. *
  1718. *   SYNOPSIS
  1719. *    success = CmdSetDate(handler,lock,name,
  1720. *        date)
  1721. *
  1722. *    BOOL CmdSetDate(struct Handler *,struct Lock *,STRPTR,
  1723. *        struct DateStamp *);
  1724. *
  1725. *   FUNCTION
  1726. *
  1727. *   INPUTS
  1728. *
  1729. *   RESULT
  1730. *
  1731. *   EXAMPLE
  1732. *
  1733. *   NOTES
  1734. *
  1735. *   BUGS
  1736. *
  1737. *   SEE ALSO
  1738. *
  1739. ****************************************************************************
  1740. *
  1741. */
  1742.  
  1743. BOOL CmdSetDate(struct Handler *handler,struct Lock *lock,STRPTR name,
  1744.    struct DateStamp *date)
  1745. {
  1746.    struct Object *object;
  1747.    LONG error;
  1748.  
  1749.    /* Check volume isn't write-protected */
  1750.  
  1751.    error=0;
  1752.    if(handler->locked)
  1753.       error=ERROR_DISK_WRITE_PROTECTED;
  1754.  
  1755.    /* Get object and set its new date */
  1756.  
  1757.    if(error==0)
  1758.    {
  1759.       object=GetObject(handler,lock,name,NULL);
  1760.       if(object!=NULL)
  1761.       {
  1762.          object=GetRealObject(object);
  1763.          CopyMem(date,&object->date,sizeof(struct DateStamp));
  1764.       }
  1765.       else
  1766.          error=IoErr();
  1767.    }
  1768.  
  1769.    /* Notify interested parties */
  1770.  
  1771.    if(error==0)
  1772.    {
  1773.       NotifyAll(handler,object,TRUE);
  1774.    }
  1775.  
  1776.    /* Return result */
  1777.  
  1778.    SetIoErr(error);
  1779.    return error==0;
  1780. }
  1781.  
  1782.  
  1783.  
  1784. /****i* ram.handler/CmdDeleteObject ****************************************
  1785. *
  1786. *   NAME
  1787. *    CmdDeleteObject --
  1788. *
  1789. *   SYNOPSIS
  1790. *    success = CmdDeleteObject(handler,lock,name)
  1791. *
  1792. *    BOOL CmdDeleteObject(struct Handler *,struct Lock *,STRPTR);
  1793. *
  1794. *   FUNCTION
  1795. *
  1796. *   INPUTS
  1797. *
  1798. *   RESULT
  1799. *
  1800. *   EXAMPLE
  1801. *
  1802. *   NOTES
  1803. *
  1804. *   BUGS
  1805. *
  1806. *   SEE ALSO
  1807. *
  1808. ****************************************************************************
  1809. *
  1810. */
  1811.  
  1812. BOOL CmdDeleteObject(struct Handler *handler,struct Lock *lock,
  1813.    STRPTR name)
  1814. {
  1815.    LONG error=0;
  1816.    struct Object *object;
  1817.  
  1818.    /* Find object and check it can be deleted */
  1819.  
  1820.    object=GetObject(handler,lock,name,NULL);
  1821.    if(object==NULL)
  1822.       error=IoErr();
  1823.  
  1824.    if(handler->locked)
  1825.       error=ERROR_DISK_WRITE_PROTECTED;
  1826.  
  1827.    if(error==0)
  1828.    {
  1829.       if(GetRealObject(object)->protection&FIBF_DELETE)
  1830.          error=ERROR_DELETE_PROTECTED;
  1831.    }
  1832.  
  1833.    /* Attempt to delete object */
  1834.  
  1835.    if(error==0)
  1836.    {
  1837.       if(!AttemptDeleteObject(handler,object))
  1838.          error=IoErr();
  1839.    }
  1840.  
  1841.    /* Return result */
  1842.  
  1843.    SetIoErr(error);
  1844.    return error==0;
  1845. }
  1846.  
  1847.  
  1848.  
  1849. /****i* ram.handler/CmdCurrentVolume ***************************************
  1850. *
  1851. *   NAME
  1852. *    CmdCurrentVolume --
  1853. *
  1854. *   SYNOPSIS
  1855. *    volume = CmdCurrentVolume(handler)
  1856. *
  1857. *    struct DosList *CmdCurrentVolume(struct Handler *);
  1858. *
  1859. *   FUNCTION
  1860. *
  1861. *   INPUTS
  1862. *
  1863. *   RESULT
  1864. *
  1865. *   EXAMPLE
  1866. *
  1867. *   NOTES
  1868. *
  1869. *   BUGS
  1870. *
  1871. *   SEE ALSO
  1872. *
  1873. ****************************************************************************
  1874. *
  1875. */
  1876.  
  1877. struct DosList *CmdCurrentVolume(struct Handler *handler)
  1878. {
  1879.    SetIoErr(0);
  1880.    return handler->volume;
  1881. }
  1882.  
  1883.  
  1884.  
  1885. /****i* ram.handler/CmdChangeMode ******************************************
  1886. *
  1887. *   NAME
  1888. *    CmdChangeMode --
  1889. *
  1890. *   SYNOPSIS
  1891. *    success = CmdChangeMode(type,thing,new_mode)
  1892. *
  1893. *    BOOL CmdChangeMode(ULONG,APTR,ULONG);
  1894. *
  1895. *   FUNCTION
  1896. *
  1897. *   INPUTS
  1898. *
  1899. *   RESULT
  1900. *
  1901. *   EXAMPLE
  1902. *
  1903. *   NOTES
  1904. *
  1905. *   BUGS
  1906. *
  1907. *   SEE ALSO
  1908. *
  1909. ****************************************************************************
  1910. *
  1911. */
  1912.  
  1913. BOOL CmdChangeMode(ULONG type,APTR thing,ULONG new_mode)
  1914. {
  1915.    struct Lock *lock;
  1916.    struct Opening *opening;
  1917.    ULONG old_mode;
  1918.    LONG error=0;
  1919.  
  1920.    /* Get the lock */
  1921.  
  1922.    if(type==CHANGE_FH)
  1923.    {
  1924.       opening=(APTR)((struct FileHandle *)thing)->fh_Arg1;
  1925.       lock=opening->file->lock;
  1926.    }
  1927.    else
  1928.       lock=thing;
  1929.  
  1930.    /* Change mode if possible */
  1931.  
  1932.    old_mode=((struct FileLock *)lock)->fl_Access;
  1933.  
  1934.    if((new_mode==ACCESS_WRITE)&&(lock->lock_count>1))
  1935.    {
  1936.       error=ERROR_OBJECT_IN_USE;
  1937.    }
  1938.    else
  1939.    {
  1940.       ((struct FileLock *)lock)->fl_Access=new_mode;
  1941.    }
  1942.  
  1943.    /* Set error code and return result */
  1944.  
  1945.    SetIoErr(error);
  1946.    return error==0;
  1947. }
  1948.  
  1949.  
  1950.  
  1951. /****i* ram.handler/CmdMakeLink ********************************************
  1952. *
  1953. *   NAME
  1954. *    CmdMakeLink --
  1955. *
  1956. *   SYNOPSIS
  1957. *    success = CmdMakeLink(handler,lock,name,reference,
  1958. *        link_type)
  1959. *
  1960. *    BOOL CmdMakeLink(struct Handler *,struct Lock *,STRPTR,APTR,
  1961. *        LONG);
  1962. *
  1963. *   FUNCTION
  1964. *
  1965. *   INPUTS
  1966. *
  1967. *   RESULT
  1968. *
  1969. *   EXAMPLE
  1970. *
  1971. *   NOTES
  1972. *
  1973. *   BUGS
  1974. *
  1975. *   SEE ALSO
  1976. *
  1977. ****************************************************************************
  1978. *
  1979. */
  1980.  
  1981. BOOL CmdMakeLink(struct Handler *handler,struct Lock *lock,STRPTR name,
  1982.    APTR reference,LONG link_type)
  1983. {
  1984.    struct Object *link,*parent,*target,*master_link;
  1985.    LONG error=0,object_type;
  1986.    PINT block_diff;
  1987.    struct MinNode *node;
  1988.  
  1989.    /* Find parent directory and possible name clash */
  1990.  
  1991.    link=GetObject(handler,lock,name,&parent);
  1992.    if(link!=NULL)
  1993.       error=ERROR_OBJECT_EXISTS;
  1994.  
  1995.    /* Determine link type */
  1996.  
  1997.    if(link_type==LINK_HARD)
  1998.    {
  1999.       target=(APTR)((struct FileLock *)reference)->fl_Key;
  2000.       if(((struct Node *)target)->ln_Pri==ST_FILE)
  2001.          object_type=ST_LINKFILE;
  2002.       else
  2003.          object_type=ST_LINKDIR;
  2004.    }
  2005.    else
  2006.    {
  2007.       object_type=ST_SOFTLINK;
  2008.       error=ERROR_NOT_IMPLEMENTED;
  2009.    }
  2010.  
  2011.    /* Check volume isn't write-protected */
  2012.  
  2013.    if(error==0)
  2014.    {
  2015.       if(handler->locked)
  2016.          error=ERROR_DISK_WRITE_PROTECTED;
  2017.    }
  2018.  
  2019.    /* Create a new link */
  2020.  
  2021.    if(error==0)
  2022.    {
  2023.       if(parent!=NULL)
  2024.       {
  2025.          link=CreateObject(handler,FilePart(name),object_type,parent);
  2026.          if(link==NULL)
  2027.             error=IoErr();
  2028.       }
  2029.       else
  2030.          error=ERROR_OBJECT_NOT_FOUND;
  2031.    }
  2032.  
  2033.    /* Store link target */
  2034.  
  2035.    if(error==0)
  2036.    {
  2037.       if(link_type==LINK_HARD)
  2038.       {
  2039.          node=target->hard_link.mln_Succ;
  2040.          if(node==NULL)
  2041.          {
  2042.             master_link=link;
  2043.             AddTail((APTR)&master_link->elements,(APTR)&target->hard_link);
  2044.          }
  2045.          else
  2046.             master_link=HARDLINK(node);
  2047.          AddTail((APTR)&master_link->elements,(APTR)&link->hard_link);
  2048.       }
  2049.       else
  2050.       {
  2051.          block_diff=SetString((APTR)&link->lock,reference);
  2052.          if(block_diff==-1)
  2053.             error=IoErr();
  2054.          else
  2055.          {
  2056.             link->block_count+=block_diff;
  2057.             handler->block_count+=block_diff;
  2058.          }
  2059.       }
  2060.    }
  2061.  
  2062.    /* Notify */
  2063.  
  2064.    if(error==0)
  2065.       NotifyAll(handler,link,FALSE);
  2066.  
  2067.    /* Return success indicator */
  2068.  
  2069.    SetIoErr(error);
  2070.    return error==0;
  2071. }
  2072.  
  2073.  
  2074.  
  2075. /****i* ram.handler/CmdWriteProtect ****************************************
  2076. *
  2077. *   NAME
  2078. *    CmdWriteProtect --
  2079. *
  2080. *   SYNOPSIS
  2081. *    success = CmdWriteProtect(handler,on,key)
  2082. *
  2083. *    BOOL CmdWriteProtect(struct Handler *,BOOL,ULONG);
  2084. *
  2085. *   FUNCTION
  2086. *
  2087. *   INPUTS
  2088. *
  2089. *   RESULT
  2090. *
  2091. *   EXAMPLE
  2092. *
  2093. *   NOTES
  2094. *
  2095. *   BUGS
  2096. *
  2097. *   SEE ALSO
  2098. *
  2099. ****************************************************************************
  2100. *
  2101. */
  2102.  
  2103. BOOL CmdWriteProtect(struct Handler *handler,BOOL on,ULONG key)
  2104. {
  2105.    LONG error;
  2106.    struct Object *root_dir;
  2107.  
  2108.    error=0;
  2109.    root_dir=handler->root_dir;
  2110.  
  2111.    if(on)
  2112.    {
  2113.       if(!handler->locked)
  2114.          root_dir->length=key;
  2115.       else
  2116.          error=ERROR_DISK_WRITE_PROTECTED;
  2117.    }
  2118.    else
  2119.    {
  2120.       if((root_dir->length!=0)&&(root_dir->length!=key))
  2121.          error=ERROR_INVALID_COMPONENT_NAME;
  2122.       else
  2123.          root_dir->length=0;
  2124.    }
  2125.  
  2126.    if(error==0)
  2127.       handler->locked=on;
  2128.  
  2129.    /* Return success indicator */
  2130.  
  2131.    SetIoErr(error);
  2132.    return error==0;
  2133. }
  2134.  
  2135.  
  2136.  
  2137. /****i* ram.handler/CmdFlush ***********************************************
  2138. *
  2139. *   NAME
  2140. *    CmdFlush --
  2141. *
  2142. *   SYNOPSIS
  2143. *    success = CmdFlush()
  2144. *
  2145. *    BOOL CmdFlush();
  2146. *
  2147. *   FUNCTION
  2148. *
  2149. *   INPUTS
  2150. *
  2151. *   RESULT
  2152. *
  2153. *   EXAMPLE
  2154. *
  2155. *   NOTES
  2156. *
  2157. *   BUGS
  2158. *
  2159. *   SEE ALSO
  2160. *
  2161. ****************************************************************************
  2162. *
  2163. */
  2164.  
  2165. BOOL CmdFlush()
  2166. {
  2167.    return TRUE;
  2168. }
  2169.  
  2170.  
  2171.  
  2172. /****i* ram.handler/CmdAddNotify *******************************************
  2173. *
  2174. *   NAME
  2175. *    CmdAddNotify --
  2176. *
  2177. *   SYNOPSIS
  2178. *    success = CmdAddNotify(handler,request)
  2179. *
  2180. *    BOOL CmdAddNotify(struct Handler *,struct NotifyRequest *);
  2181. *
  2182. *   FUNCTION
  2183. *
  2184. *   INPUTS
  2185. *
  2186. *   RESULT
  2187. *
  2188. *   EXAMPLE
  2189. *
  2190. *   NOTES
  2191. *
  2192. *   BUGS
  2193. *
  2194. *   SEE ALSO
  2195. *
  2196. ****************************************************************************
  2197. *
  2198. */
  2199.  
  2200. BOOL CmdAddNotify(struct Handler *handler,struct NotifyRequest *request)
  2201. {
  2202.    LONG error=0;
  2203.    struct Notification *notification;
  2204.    struct Object *object;
  2205.  
  2206.    notification=AllocMem(sizeof(struct Notification),MEMF_CLEAR);
  2207.    if(notification==NULL)
  2208.       error=IoErr();
  2209.  
  2210.    if(error==0)
  2211.    {
  2212.       notification->request=request;
  2213.       request->nr_Flags&=~NRF_MAGIC;
  2214.  
  2215.       object=GetObject(handler,NULL,request->nr_FullName,NULL);
  2216.  
  2217.       if(object!=NULL)
  2218.       {
  2219.          AddTail((APTR)&object->notifications,(APTR)notification);
  2220.          if((request->nr_Flags&NRF_NOTIFY_INITIAL)!=0)
  2221.             Notify(handler,notification);
  2222.       }
  2223.       else
  2224.          AddTail((APTR)&handler->notifications,(APTR)notification);
  2225.    }
  2226.  
  2227.    /* Return success indicator */
  2228.  
  2229.    SetIoErr(error);
  2230.    return error==0;
  2231. }
  2232.  
  2233.  
  2234.  
  2235. /****i* ram.handler/CmdRemoveNotify ****************************************
  2236. *
  2237. *   NAME
  2238. *    CmdRemoveNotify --
  2239. *
  2240. *   SYNOPSIS
  2241. *    success = CmdRemoveNotify(handler,request)
  2242. *
  2243. *    BOOL CmdRemoveNotify(struct Handler *,struct NotifyRequest *);
  2244. *
  2245. *   FUNCTION
  2246. *
  2247. *   INPUTS
  2248. *
  2249. *   RESULT
  2250. *
  2251. *   EXAMPLE
  2252. *
  2253. *   NOTES
  2254. *
  2255. *   BUGS
  2256. *
  2257. *   SEE ALSO
  2258. *
  2259. ****************************************************************************
  2260. *
  2261. */
  2262.  
  2263. BOOL CmdRemoveNotify(struct Handler *handler,struct NotifyRequest *request)
  2264. {
  2265.    struct Notification *notification;
  2266.  
  2267.    notification=FindNotification(handler,request);
  2268.    Remove((APTR)notification);
  2269.    FreeMem(notification,sizeof(struct Notification));
  2270.  
  2271.    return TRUE;
  2272. }
  2273.  
  2274.  
  2275.  
  2276.